/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.appspot.nnaplanner.DAL;

import com.appspot.nnaplanner.Stop;
import java.util.ArrayList;
import javax.jdo.Query;
import javax.jdo.annotations.*;
import java.util.Date;
import java.util.List;

/**
 *
 * @author david
 */
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class DALConnection {
    //mot sure if I need this?

    @PrimaryKey
    @Persistent
    private String _id;
    @Persistent
    private String _stopID;
    @Persistent
    private String _stopName;
    @Persistent
    private String _destinationID;
    @Persistent
    private String _destinationName;
    @Persistent
    private int _departures;
    @Persistent(defaultFetchGroup = "true")
    private List<Date> _times;
    @Persistent(defaultFetchGroup = "true")
    private List<Integer> _durations;
    @Persistent(defaultFetchGroup = "true")
    private List<String> _descriptions;
    @Persistent(defaultFetchGroup = "true")
    private List<String> _keywords;

    /**
     * @return The list of descriptions for each time you have
     */
    public List<String> getDescriptions() {
        return _descriptions;
    }

    /**
     * @param _descriptions The ist of descriptions you want to make persistent
     */
    public void setDescriptions(List<String> _descriptions) {
        this._descriptions = _descriptions;
    }

    /**
     * Default constructor
     */
    public DALConnection() {
        _stopID = "";
        _destinationID = "";
        _departures = 0;
        _times = new ArrayList<Date>();
        _durations = new ArrayList<Integer>();
        _descriptions = new ArrayList<String>();
    }

    /**
     * The Id of the stop for this connection
     * @param stop_id The Id for this stop
     */
    public void setStop(String stop_id) {
        _stopID = stop_id;
    }

    /**
     * Sets the ID for this stop
     * @param id The id for this stop
     */
    public void setID(String id) {
        _id = id;
    }

    /**
     * @return The stop id for this connection
     */
    public String getStopID() {
        return _stopID;
    }

    /**
     * The actual Id for this connection. This is a concantination of the stop
     * and destiniation ids
     * @return The id of this stop
     */
    public String getID() {
        if (_id != null) {
            return _id;
        } else {
            return getStopID() + getDestinationID();
        }
    }

    /**
     * This gets all connections for a specific stop, bused onthe stops id
     * @param stopID The id of the stop you want o get connections for
     * @return A list of connections based onthe provided id
     */
    public List<DALConnection> getConnectionsFor(String stopID) {
        List<DALConnection> result = null;
        Query q = DAL.newQuery();
        q.setClass(DALConnection.class);
        q.setFilter("_stopID == pStopID");
        q.declareParameters("String pStopID");
        result = (List<DALConnection>) q.execute(stopID);
        return result;
    }

    /**
     * Gets all connections from the database
     * @return a List of connections found int he data store
     */
    public List<DALConnection> getAllConnections() {
        return getAllConnections(0, 0);
    }

    /**
     * Gets x number of connections from the start. For example,
     * get the limit=10 records after the start=32
     * @param start Where to start retrtieving records
     * @param limit The number of records to retrieve
     * @return a collectioon of records
     */
    public List<DALConnection> getAllConnections(int start, int limit) {
        Query q = DAL.newQuery();
        q.setClass(DALConnection.class);
        if (start + limit > 0) {
            q.setRange(start, start + limit);
        }
        return (List<DALConnection>) q.execute();
    }

    /**
     * Gets x number of connections from the start. For example,
     * get the limit=10 records after the start=32
     * @param start Where to start retrtieving records
     * @param limit The number of records to retrieve
     * @param keyword The search word
     * @return a collection of connections matching parameters provided
     */
    public List<DALConnection> getAllConnections(int start, int limit, String keyword) {
        Query q = DAL.newQuery();
        q.setClass(DALConnection.class);
        if (start + limit > 0) {
            q.setRange(start, start + limit);
        }

        if (!keyword.isEmpty()) {
            q.setFilter("_keywords == pKeyword");
            q.declareParameters("String pKeyword");
            //query.addFilter("_name",Query.FilterOperator.GREATER_THAN_OR_EQUAL, "S");
        } else {
            return getAllConnections(start, limit);
        }
        return (List<DALConnection>) q.execute(keyword);
    }

    /**
     * Removes a matching departure based on the time provided
     * Note that all
     * @param time you want to remove
     */
    public void removeTime(Date time) {
        _durations.remove(_times.indexOf(time));
        _descriptions.remove(_times.indexOf(time));
        _times.remove(time);
    }

    /**
     * @return A list of departure times based on this connection
     */
    public List<Date> getTimes() {
        return _times;
    }

    /**
     * @return the list of durations each departure has
     */
    public List<Integer> getDurations() {
        return _durations;
    }

    /**
     * Use this to set the Stop object for this connection
     * @param ds
     */
    public void setStop(DALStop ds) {
        setStop(ds.getID());
        setStopName(ds.getName());
    }

    /**
     * GEts a Connection based onthe the provided ID
     * @param ID The connectin ID you want to get
     * @return The full connection object
     */
    public DALConnection getByID(String ID) {
        DALConnection dc = new DALConnection();
        dc = DAL.getByID(dc, ID);
        DAL.get().getPersistenceManager().close();
        return dc;
    }

    /**
     * Sets the destinaton id for this connection
     * @param destinationID
     */
    public void setDestination(String destinationID) {
        _destinationID = destinationID;
    }

    /**
     * Set the destination stop for this connection
     * @param ds the stop you want as the destination
     */
    public void setDestination(DALStop ds) {
        setDestination(ds.getID());
        setDestinationName(ds.getName());
    }

    /**
     * Gets the destination id
     * @return The distentation Id for this connection
     */
    public String getDestinationID() {
        return _destinationID;
    }

    /**
     * Save this object to the datastore
     * @return The object id
     */
    public String save() {
        return save(this);
    }

    /**
     * Save the DalConnection that is provided as the parameter
     * @param dc the connection youwant to save
     * @return The id of the saved
     */
    public String save(DALConnection dc) {
        if (_stopID.trim().isEmpty()) {
            throw new IllegalArgumentException("Stop id must be defined");
        }
        DAL.save(dc);
        DAL.get().getPersistenceManager().close();
        return dc.getID();
    }

    /**
     * @return The number of departures fromt his connection
     */
    public int getDepartures() {
        return _departures;
    }

    /**
     * Set the count of departures for the connection
     * @param departures the number of departures
     */
    public void setDepartures(int departures) {
        this._departures = departures;
    }

    /**
     * Adds a departure to this connection
     * @param departureTime The time of departure
     * @param duration The duration of the departure
     * @param description The description for this departure
     */
    public void addDeparture(Date departureTime, Integer duration, String description) {
        if (_times == null) {
            _times = new ArrayList<Date>();
            _durations = new ArrayList<Integer>();
            _descriptions = new ArrayList<String>();
        }
        _times.add(departureTime);
        _durations.add(duration);
        _descriptions.add(description);
    }

    /**
     * Keywords for this connection
     * @return a ist of keywords for this departure
     */
    public List<String> getKeywords() {
        return _keywords;
    }

    /**
     * @param keywords Set the keywords for this departure
     */
    public void setKeywords(List<String> keywords) {
        this._keywords = keywords;
    }

    /**
     * Gets the name of the destination for this connection
     * @return The connectin name
     */
    public String getDestinationName() {
        return _destinationName;
    }

    /**
     * Sets the destination for this cobject
     * @param destinationName
     */
    public void setDestinationName(String destinationName) {
        this._destinationName = destinationName;
    }

    /**
     * Returns the Name for this stop
     * @return The stop name
     */
    public String getStopName() {
        return _stopName;
    }

    /**
     * Sets the stop name for this object
     * @param stopName
     */
    public void setStopName(String stopName) {
        this._stopName = stopName;
    }

    /**
     * Set the list of durations for the departures in this stop
     * @param durations
     */
    public void setDurations(List<Integer> durations) {
        this._durations = durations;
    }

    /**
     * Set the departure times for this object
     * @param times the departure times
     */
    public void setTimes(List<Date> times) {
        this._times = times;
    }

    /**
     * Sets the departures for this connection. Make sure they all have the same size
     * @param times The departure times
     * @param durations The departure durations
     * @param descriptions The descriptions
     */
    public void setDepartures(List<Date> times, List<Integer> durations, List<String> descriptions) {
        this._times = times;
        this._durations = durations;
        this._descriptions = descriptions;
    }

    /**
     * The ID of the object is its string representation
     * @return
     */
    @Override
    public String toString() {
        return this.getID();
    }

    /**
     * Delete this connection
     * @return True if object deleted
     */
    public boolean delete() {
        return delete(this);
    }

    /**
     * Delete the connection provided as the parameter
     * @param dc The connection you want to delete
     * @return True if object deleted
     */
    public boolean delete(DALConnection dc) {
        DAL.delete(dc, dc.getID());
        return true;
    }

    /**
     * Overidden property, so this object works in collections
     * @param obj Teh object you want to chec for equality
     * @return true if equal
     */
    @Override
    public boolean equals(Object obj) {
        if (obj.getClass() == this.getClass()) {
            if (this.getID().equals(obj.toString())) {
                return true;
            }
            return false;
        }
        return false;
    }

    /**
     * The hash code for this object
     * @return The object hascode
     */
    public int hashCode() {
        return this.getID().hashCode();
    }
}
